package com.funmi.lizip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.funmi.lizip.common.base.R;
import com.funmi.lizip.common.base.ResultCode;
import com.funmi.lizip.common.exception.ApplicationException;
import com.funmi.lizip.entity.*;
import com.funmi.lizip.entity.dto.photo.PhotoAddRequest;
import com.funmi.lizip.entity.dto.photo.PhotoSQueryRequest;
import com.funmi.lizip.entity.dto.photo.PhotoUpdateRequest;
import com.funmi.lizip.entity.dto.photo.PhotoValidRequest;
import com.funmi.lizip.entity.enums.PathEnum;
import com.funmi.lizip.entity.vo.StatisticsPhotoVo;
import com.funmi.lizip.mapper.PhotoMapper;
import com.funmi.lizip.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.funmi.lizip.utils.FileFormatUtil;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yeyg
 * @since 2022-11-02
 */
@Service
public class PhotoServiceImpl extends ServiceImpl<PhotoMapper, Photo> implements PhotoService {

    @Autowired
    private PhotoMapper photoMapper;
    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private InfraredAnimalService infraredAnimalService;
    @Autowired
    private CameraService cameraService;

    /**
     * 人工修改红外相机图片
     *
     * @param id
     * @param updateRequest
     * @return
     */
    @Override
    public Boolean updateById(int id, PhotoUpdateRequest updateRequest) {
        if (id <= 0) {
            R.success().code(ResultCode.CAMERA_NOT_FOUND);
            return false;
        }
        Photo photo = new Photo();
        BeanUtils.copyProperties(updateRequest, photo);
        photo.setStatus(3);
        photo.setChangeAt(LocalDateTime.now());
        photo.setId(id);
        int i = photoMapper.updateById(photo);
        // 修改图片详情
        // PhotoLog photoLog = new PhotoLog();
        // photoLogService.updateById(photoLog);
        if (i == 1) {
            return true;
        }
        R.success().code(ResultCode.CAMERA_CHANGE_FAILED);
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insert(PhotoAddRequest request) throws IOException {
        // 转换
        ArrayList<Photo> photos = new ArrayList<>();
        for (String file : request.getFileNames()) {
            Photo photo = new Photo();
            LocalDateTime now = LocalDateTime.now();
            String s="" + now.getYear() + "-" +  now.getMonthValue() + "-" +  now.getDayOfMonth();
            String camera_id = "0000";
            if (!ObjectUtils.isEmpty(request.getPointNo())){
                if (!request.getPointNo().equals(0)){
                    camera_id = request.getPointNo().toString();
                    // 查询相关相机id 并 设置
                    Camera camera = new Camera();
                    camera.setPointNo(request.getPointNo().toString());
                    Camera one = cameraService.getOne(new QueryWrapper<>(camera));
                    photo.setCameraId(one.getId());
                }
            }

            // 将图片名称 增加时间戳 防止名称重复覆盖
            long l = System.currentTimeMillis();
            String fileName = s+ "\\"+ l + " " + file;
            File dest = new File(PathEnum.PATH.getText() +"\\"+"CameraPhoto"+"\\"+camera_id+"\\"+ fileName);
            // 将暂存的图片移动到指定文件夹中
            // 文件夹名称
            Path directories = Files.createDirectories(dest.getParentFile().toPath());
            File startFile = new File(PathEnum.PATH.getText() +"\\"+ file);
            boolean b = startFile.renameTo(dest);
            if (!b){
                throw new ApplicationException("图片保存失败");
            }
            // 文件大小
            photo.setSize(BigDecimal.valueOf((double) dest.length() / 1024 / 1024).setScale(2,RoundingMode.HALF_UP).doubleValue());
            BeanUtils.copyProperties(request, photo);
            // 创建时间
            photo.setCreateAt(LocalDateTime.now());
            // 文件名
            photo.setFileName(camera_id + "\\" + fileName);

            BufferedImage read = ImageIO.read(dest);
            // 如果图片为空，则表示为视频
            if (ObjectUtils.isEmpty(read)) {
                photo.setFileType("2");
                photo.setFileFormat(request.getFileFormat());
            }else {
                // 长宽高，大小
                double w;
                w = read.getWidth();
                photo.setWidth(w);
                w = read.getHeight();
                photo.setHeight(w);
                // 文件类型 照片
                photo.setFileType("1");
                // 文件格式
                photo.setFileFormat(FileFormatUtil.fileFormatUtil(dest.getAbsolutePath()));
            }
            // 设置初始为未识别
            if(ObjectUtils.isEmpty(photo.getStatus())) {
                photo.setStatus(1);
            }
            photos.add(photo);

        }
        for (Photo photo : photos) {
            photoMapper.insert(photo);
        }
        return true;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R updateValid(HashMap<String,  ArrayList<Integer>> request) {
        Photo photo = new Photo();
        photo.setCreateAt(LocalDateTime.now());
        // 从登录态中获取
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        String name = authentication.getName();
        QueryWrapper<AdminUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", name);
        AdminUser one = adminUserService.getOne(userQueryWrapper);
        if (ObjectUtils.isEmpty(one)){
            return R.fail().message("账号错误  没有权限");
        }

        photo.setChangeUserId(one.getId());
        photo.setStatus(3);
        ArrayList<Integer> ids = request.get("id");
        for (Integer integer : ids) {
            Photo id = photoMapper.selectById(integer);
            photo.setValid(!id.getValid());
            photo.setId(integer);
            int i = photoMapper.updateById(photo);
            if (i != 1) {
                return R.fail().message("修改失败");
            }
        }
        return R.success().message("修改成功");


    }

    /**
     * 要求 统计分析展示: 按物种名称、相机位置、布设时间汇总统计物种种类、物种数量及人为干扰数量?
     *
     * @return
     */
    @Override
    public HashMap<String, List<T>> statistical() {




        return null;
    }

    /**
     * 图片统计
     * @return
     */
    private Integer i = 0;
    @Override
    public StatisticsPhotoVo getStatistics(PhotoSQueryRequest request) {
        StatisticsPhotoVo statisticsPhotoVo = new StatisticsPhotoVo();
        // 总的
        QueryWrapper<Photo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("animal_type","兽类");
        queryWrapper.eq("is_valid", 1);
        if (!ObjectUtils.isEmpty(request)){
            queryWrapper.between("shot_at",
                    (ObjectUtils.isEmpty(request.getStartAt()))? (LocalDateTime.of(2019, 10, 12, 6, 30)): request.getStartAt(),
                    (ObjectUtils.isEmpty(request.getEndAt()))? (LocalDateTime.now()):request.getEndAt());
        }

        List<Photo> photos = photoMapper.selectList(queryWrapper);
        if(!ObjectUtils.isEmpty(photos) && photos.size() > 0) {
            photos.forEach(photo -> {
                if (!ObjectUtils.isEmpty(photo) && !ObjectUtils.isEmpty(photo.getAnimalNumber())) {
                    i += (photo.getAnimalNumber());
                }
            });
            statisticsPhotoVo.setMammals(i);
            i = 0;
        }
        QueryWrapper<Photo> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("animal_type","鸟类");
        queryWrapper2.eq("is_valid", 1);
        if (!ObjectUtils.isEmpty(request)){
            queryWrapper2.between("shot_at",
                    (ObjectUtils.isEmpty(request.getStartAt()))? (LocalDateTime.of(2019, 10, 12, 6, 30)): request.getStartAt(),
                    (ObjectUtils.isEmpty(request.getEndAt()))? (LocalDateTime.now()):request.getEndAt());
        }
        List<Photo> photos2 = photoMapper.selectList(queryWrapper2);
        if(!ObjectUtils.isEmpty(photos2) && photos2.size() > 0) {
            photos2.forEach(photo -> {
                if (!ObjectUtils.isEmpty(photo) && !ObjectUtils.isEmpty(photo.getAnimalNumber())) {
                i += (photo.getAnimalNumber());
            }});
            statisticsPhotoVo.setBird(i);
            i = 0;
        }

        QueryWrapper<Photo> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("animal_type","其他");
        queryWrapper3.eq("is_valid", 1);
        if (!ObjectUtils.isEmpty(request) ){
            queryWrapper3.between("shot_at",
                    (ObjectUtils.isEmpty(request.getStartAt()))? (LocalDateTime.of(2019, 10, 12, 6, 30)): request.getStartAt(),
                    (ObjectUtils.isEmpty(request.getEndAt()))? (LocalDateTime.now()):request.getEndAt());
        }
        List<Photo> photos3 = photoMapper.selectList(queryWrapper3);
        if(!ObjectUtils.isEmpty(photos3) && photos3.size() > 0) {
            photos3.forEach(photo -> {if (!ObjectUtils.isEmpty(photo) && !ObjectUtils.isEmpty(photo.getAnimalNumber())) {
                i += (photo.getAnimalNumber());
            }});
            statisticsPhotoVo.setOther(i);
            i = 0;
        }

        QueryWrapper<Photo> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.eq("animal_type","人类");
        queryWrapper4.eq("is_valid", 1);
        if (!ObjectUtils.isEmpty(request)){
            queryWrapper4.between("shot_at",
                    (ObjectUtils.isEmpty(request.getStartAt()))? (LocalDateTime.of(2019, 10, 12, 6, 30)): request.getStartAt(),
                    (ObjectUtils.isEmpty(request.getEndAt()))? (LocalDateTime.now()):request.getEndAt());
        }
        List<Photo> photos4 = photoMapper.selectList(queryWrapper4);
        if(!ObjectUtils.isEmpty(photos4) && photos4.size() > 0) {
            photos4.forEach(photo -> {if (!ObjectUtils.isEmpty(photo) && !ObjectUtils.isEmpty(photo.getAnimalNumber())) {
                i += (photo.getAnimalNumber());
            }});
            statisticsPhotoVo.setMan(i);
            i = 0;
        }

        // 单位时间内照片总数
        QueryWrapper<Photo> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.eq("is_valid", 1);
        if (!ObjectUtils.isEmpty(request)){
            queryWrapper5.between("shot_at",
                    (ObjectUtils.isEmpty(request.getStartAt()))? (LocalDateTime.of(2019, 10, 12, 6, 30)): request.getStartAt(),
                    (ObjectUtils.isEmpty(request.getEndAt()))? (LocalDateTime.now()):request.getEndAt());
        }
        Long aLong = photoMapper.selectCount(queryWrapper5);
        statisticsPhotoVo.setPhotoTotal(aLong);



        // 固定动物名称数量
        QueryWrapper<Photo> queryWrapper1 = new QueryWrapper<>();
        Map<String, Integer> animalNumber = new HashMap<>();

        if (!ObjectUtils.isEmpty(request.getAnimalName())){
            queryWrapper1.eq("animal_name", request.getAnimalName());
        }
        List<Photo> photos1 = photoMapper.selectList(queryWrapper1);
        photos1.forEach(photo -> {
            if(!ObjectUtils.isEmpty(photo)) {
                i += photo.getAnimalNumber();
            }
        });
        animalNumber.put(ObjectUtils.isEmpty(request.getAnimalName())?"所有动物":request.getAnimalName(), i);
        statisticsPhotoVo.setAnimalNumber(animalNumber);
        i = 0;


        // 不同动物的数量
        Map<String, Integer> animalsNumber = new HashMap<>();
        List<InfraredAnimal> list = infraredAnimalService.list();
        list.forEach(InfraredAnimal ->{
            QueryWrapper<Photo> photoQueryWrapper = new QueryWrapper<>();
            photoQueryWrapper.eq("animal_name", InfraredAnimal.getName());
            photoQueryWrapper.eq("is_valid", 1);
            List<Photo> photos5 = photoMapper.selectList(photoQueryWrapper);
            photos5.forEach(photo -> {
                i += photo.getAnimalNumber();
            });
            if (!i.equals(0)) {
                animalsNumber.put(InfraredAnimal.getName(), i);
                i = 0;
            }
        });
        statisticsPhotoVo.setAnimalsNumber(animalsNumber);
        return statisticsPhotoVo;
    }


}
